package com.xms.sdk.api.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xms.schema.entity.Attribute;
import com.xms.schema.extension.AttributeExt;
import com.xms.schema.service.attribute.IAttributeFinderService;
import com.xms.schema.service.entity.IEntityFinderService;
import com.xms.sdk.api.model.DataUpdateModel;
import com.xms.sdk.api.model.SetEntityRecordStateModel;
import com.xms.sdk.extensions.EntityWrapper;
import com.xms.sdk.service.IDataUpdater;
import com.xms.utils.CollectionUtil;
import com.xms.utils.StringUtil;
import com.xms.utils.UUIDUtil;
import com.xms.web.framework.controller.ApiBaseController;
import com.xms.web.framework.model.JsonResultObject;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * <p>
 * DataUpdatererController
 * </p>
 *
 * @author migo
 * @since 2021/9/16
 */
@RestController
@RequestMapping("{org}/api/data")
public class DataUpdaterController extends ApiBaseController {
    private IEntityFinderService _entityFinderService;
    private IAttributeFinderService _attributeFinderService;
    private IDataUpdater _dataUpdater;

    public DataUpdaterController(IEntityFinderService entityFinderService
            , IAttributeFinderService attributeFinderService
            , IDataUpdater dataUpdater)
    {
        _entityFinderService = entityFinderService;
        _attributeFinderService = attributeFinderService;
        _dataUpdater = dataUpdater;
    }

    @ApiOperation("更新记录")
    @PostMapping("update")
    public JsonResultObject post(@RequestBody DataUpdateModel model) throws Exception {
        if(UUIDUtil.isEmpty(model.EntityId) && StringUtil.isEmpty(model.EntityName)){
            return JNotSpecifiedParams("entityid", "entityname");
        }
        if(StringUtil.isEmpty(model.Data)){
            return JNotSpecifiedParams("data");
        }
        com.xms.schema.entity.Entity entityMeta = null;
        if (UUIDUtil.notEmpty(model.EntityId))
        {
            entityMeta = _entityFinderService.getById(model.EntityId);
        }
        else if (StringUtil.notEmpty(model.EntityName))
        {
            entityMeta = _entityFinderService.getByName(model.EntityName);
        }
        if (entityMeta == null)
        {
            return JNotFound();
        }
        List<Attribute> childAttributes = _attributeFinderService.getByEntityName(entityMeta.getName());
        Attribute primaryAttr = childAttributes.stream().filter(n -> AttributeExt.typeIsPrimaryKey(n)).findFirst().get();
        if (model.Data.startsWith("["))
        {
            //var details = new List<Entity>();
            JSONArray items = JSONArray.parseArray(StringUtil.urlDecode(model.Data));
            if (items.size() > 0)
            {
                Iterator childIter = items.iterator();
                while(childIter.hasNext())
                {
                    JSONObject root = (JSONObject)childIter.next();
                    com.xms.core.data.Entity detail = new com.xms.core.data.Entity(entityMeta.getName());
                    Iterator childItemIter = root.entrySet().iterator();
                    while(childItemIter.hasNext()) {
                        Map.Entry entry = (Map.Entry) childItemIter.next();
                        String key = entry.getKey().toString().toLowerCase();
                        Object value = entry.getValue();
                        if (key.equalsIgnoreCase("id"))
                        {
                            detail.setIdValue(UUIDUtil.get(value.toString()), primaryAttr.getName());
                        }
                        else
                        {
                            Attribute attr = childAttributes.stream().filter(n -> n.getName().equalsIgnoreCase(key)).findFirst().orElse(null);
                            if (attr != null)
                            {
                                detail.setValue(key, EntityWrapper.wrapAttributeValue(detail, _entityFinderService, attr, value.toString()));
                            }
                        }
                    }
                    _dataUpdater.update(detail);
                }
            }
            return JUpdateSuccess();
        }
        else
        {
            com.xms.core.data.Entity detail = new com.xms.core.data.Entity(entityMeta.getName());
            JSONObject root = JSONObject.parseObject(StringUtil.urlDecode(model.Data));
            Iterator childItemIter = root.entrySet().iterator();
            while(childItemIter.hasNext()) {
                Map.Entry entry = (Map.Entry) childItemIter.next();
                String key = entry.getKey().toString().toLowerCase();
                Object value = entry.getValue();
                if (key.equalsIgnoreCase("id"))
                {
                    detail.setIdValue(UUIDUtil.get(value.toString()), primaryAttr.getName());
                }
                else
                {
                    Attribute attr = childAttributes.stream().filter(n -> n.getName().equalsIgnoreCase(key)).findFirst().orElse(null);
                    if (attr != null)
                    {
                        detail.setValue(key, EntityWrapper.wrapAttributeValue(detail, _entityFinderService, attr, value.toString()));
                    }
                }
            }
            _dataUpdater.update(detail);
        }
        return JUpdateSuccess();
    }

    @ApiOperation("更改记录状态")
    @PostMapping("setstate")
    public JsonResultObject setState(@RequestBody SetEntityRecordStateModel model) throws Exception {
        if (CollectionUtil.isEmpty(model.RecordId))
        {
            return JNotSpecifiedRecord();
        }
        com.xms.schema.entity.Entity entityMeta = _entityFinderService.getById(model.EntityId);
        Attribute primaryKey = _attributeFinderService.getPrimaryKey(model.EntityId);
        boolean result = false;
        for (UUID item : model.RecordId)
        {
            com.xms.core.data.Entity entity = new com.xms.core.data.Entity(entityMeta.getName());
            entity.setIdName(primaryKey.getName());
            entity.setIdValue(item);
            entity.setValue("statecode", model.State);
            result = _dataUpdater.update(entity);
        }

        return result ? JUpdateSuccess() : JUpdateFailure("");
    }
}
